﻿/***********************************************************************
 * Module:  CPFLauncher.h
 * Author:  ZHANGHASI
 * Modified: 2020年12月7日 下午 3:50:05
 * Purpose: Declaration of the class CPFLauncher
 ***********************************************************************/

#ifndef __CPFLAUNCHER_H__
#define __CPFLAUNCHER_H__


#include "CPF/CPFObject.h"



/**
 * \class   CPF_PluginState
 *
 * \brief   插件状态.
 *
 * \author  zhanghs
 * \date    2021/3/30
 */
enum CPF_PluginState
{
    STATE_Unknow = 0,   // 未知
    STATE_LOAD = 1,     // 加载
    STATE_START,        // 启动
    STATE_STOP,         // 停止
    STATE_UNLOAD,       // 卸载
};


class CPFActivator;
/**
 * \brief 插件信息.
 * \author zhanghs
 * \date 2021/4/22
**/
struct CPF_PluginInfo 
{
    std::string describe;     // 插件描述
    CPFActivator* activator;    // 插件行动器对象
    void* handle;   // 句柄对象
    int state;      // 插件状态
    // 构造函数
    CPF_PluginInfo()
    {
        describe = "";
        activator = nullptr;
        handle = nullptr;
        state = 0;
    }
};

/**
 * \class   CPFLauncher
 *
 * \brief   插件启动器.
 *
 * \author  zhanghs
 * \date    2020/12/8
 */
class CPF_EXPORT CPFLauncher
    : public CPFObject
{
public:

    /**
     * \fn  static CPFLauncher* CPFLauncher::instance();
     *
     * \brief   单例模式.
     *
     * \author  zhanghs
     * \date    2020/12/9
     *
     * \return  返回单例对象.
     */
    static CPFLauncher* instance();

public:

    /**
     * \fn  bool CPFLauncher::load(std::string name);
     *
     * \brief   加载插件.
     *
     * \author  zhanghs
     * \date    2020/12/8
     *
     * \param   name    插件名称.
     *
     * \return  返回加载结果.
     */
    bool load(std::string name);

    /**
     * \fn  bool CPFLauncher::unload(std::string plugin);
     *
     * \brief   卸载插件.
     *
     * \author  zhanghs
     * \date    2020/12/8
     *
     * \param   plugin  插件名称.
     *
     * \return  返回卸载结果.
     */
    bool unload(std::string name);

    /**
     * \fn  bool CPFLauncher::start(void);
     *
     * \brief   启动插件.
     *
     * \author  zhanghs
     * \date    2020/12/8
     *
     * \return  返回启动结果.
     */
    bool start(void);

    /**
     * \fn  bool CPFLauncher::stop(void);
     *
     * \brief   停止插件.
     *
     * \author  zhanghs
     * \date    2020/12/8
     *
     * \return  返回厅组织结果.
     */
    bool stop(void);

    /**
     * \fn  void CPFLauncher::addPath(std::string path);
     *
     * \brief   添加搜索插件路径.
     *
     * \author  zhanghs
     * \date    2020/12/8
     *
     * \param   path    插件路径.
     */
    void addPath(std::string path);

    /**
     * \fn  void CPFLauncher::removePath(std::string path);
     *
     * \brief   删除搜索插件路径.
     *
     * \author  zhanghs
     * \date    2020/12/8
     *
     * \param   path    插件路径.
     */
    void removePath(std::string path);

    /**
     * \fn  std::string CPFLauncher::defaultPath(void);
     *
     * \brief   默认插件路径.
     *
     * \author  zhanghs
     * \date    2020/12/8
     *
     * \return  默认路径.
     */
    std::string defaultPath(void);

protected:
    /**
    * \fn  CPFLauncher::CPFLauncher();
    *
    * \brief   构造函数.
    *
    * \author  zhanghs
    * \date    2020/12/8
    */
    CPFLauncher();

    /**
    * \fn  virtual CPFLauncher::~CPFLauncher();
    *
    * \brief   析构函数.
    *
    * \author  zhanghs
    * \date    2020/12/8
    */
    virtual ~CPFLauncher();
    /**
     * \fn  void CPFLauncher::init();
     *
     * \brief   初始化对象.
     *
     * \author  zhanghs
     * \date    2020/12/8
     */
    void init();

    /**
     * \fn  void CPFLauncher::createDefaultDir();
     *
     * \brief   创建默认插件目录.
     *
     * \author  zhanghs
     * \date    2020/12/8
     */
    void createDefaultDir();

    /**
     * \fn  std::string CPFLauncher::searchPluginFile(std::string plugin);
     *
     * \brief   从插件路径下搜索插件.
     *
     * \author  zhanghs
     * \date    2020/12/9
     *
     * \param   plugin  插件名称.
     *
     * \return  插件完整相对路径.
     */
    std::string searchPluginFile(std::string plugin);

    /**
     * \fn  void CPFLauncher::getFiles(std::string path, std::vector<std::string>& files);
     *
     * \brief   获取指定路径下插件文件，不包含子文件夹.
     *
     * \author  zhanghs
     * \date    2020/12/9
     *
     * \param   path    指定目录.
     * \param   files   插件动态库.
     */
    void getFiles(std::string path, std::vector<std::string>& files);

    /**
     * \fn  void* CPFLauncher::getSymbol(void* handle, const std::string& symbol);
     *
     * \brief   获取指定库下的函数符号.
     *
     * \author  zhanghs
     * \date    2020/12/9
     *
     * \param   handle  库句柄.
     * \param   symbol  符号名.
     *
     * \return  函数符号.
     */
    void* getSymbol(void* handle, const std::string& symbol);

    /**
     * \fn  bool CPFLauncher::stopAcitvator(std::string name);
     *
     * \brief   停止行动器.
     *
     * \author  zhanghs
     * \date    2020/12/9
     *
     * \param   name    行动器名称.
     *
     * \return  返回操作结果.
     */
    bool stopActivator(std::string name);

    /**
     * \fn  bool CPFLauncher::startActivator(std::string name);
     *
     * \brief   开启行动器.
     *
     * \author  zhanghs
     * \date    2020/12/9
     *
     * \param   name    行动器名称.
     *
     * \return  返回操作结果.
     */
    bool startActivator(std::string name);

    /**
     * \fn  bool CPFLauncher::unloadHandle(std::string name);
     *
     * \brief   卸载动态句柄.
     *
     * \author  zhanghs
     * \date    2020/12/9
     *
     * \param   name    句柄名称.
     *
     * \return  返回操作结果.
     */
    bool unloadHandle(std::string name);
    /**
     * \fn  void CPFLauncher::updateLibraryState(std::string name, int state);
     * \brief   更新某个插件状态.
     * \author  Zhanghs
     * \date    2021/3/30
     * \param   name    插件名称.
     * \param   state   插件状态.
     */
    //void updateLibraryState(std::string name, int state);

private:
    // 插件搜索路径
    std::vector<std::string> m_vectPluginPath;
//     // 插件行动器对象
//     hash_map<std::string, CPFActivator*> m_hashActivator;
//     // 句柄对象
//     hash_map<std::string, void*> m_hashLibraryHand;
//     // 插件状态 卸载后直接删除
//     hash_map<std::string, int> m_hashLibraryState;

    // 加载的插件信息
    hash_map<std::string, CPF_PluginInfo> m_hashPluginsInfo;
};
#endif // __CPFLAUNCHER_H__
